#!/usr/bin/env python
# -*- coding:utf-8 -*-

import time

from jujuc.jujuc import Jujube, BaseJob, SendRecvAction

from jujuc import log

#######################################################################

SERVICE = 'ECHO'

class   ClientJob(BaseJob) :
    def __init__(self, peer_address, times=10, bytes=0) :
        self.peer_address = peer_address
        self.times = times
        self.pad_bytes = bytes
        self.count = 0
        self.action = None

        self.time_start = 0
        self.time_stop  = 0
        self.count_bytes = 0
        # __init__

    def currentAction(self) :
        return self.action
        # currentAction()

    def nextAction(self) :
        if self.action is None :
            # the first time
            self.time_start = time.time()
        #if self.action :
        #    print 'BACK: %s [reason:%s]' % (`self.action.result`, `self.action.reason`)
        if self.count >= self.times :
            # the last time
            self.time_stop = time.time()
            time_last = self.time_stop - self.time_start
            tps = self.times / time_last
            bindwidth = self.count_bytes / time_last
            if bindwidth > 1048576 :
                bindwidth = '%.2f MB/s' % (bindwidth / 1048576.0)
            elif bindwidth > 1024 :
                bindwidth = '%.2f KB/s' % (bindwidth / 1024.0)
            else :
                bindwidth = '%.2f B/s' % (bindwidth / 1.0)
            log.info('times:%d, time-last:%.2f seconds, tps=%.2f, bindwidth=%s', self.times, time_last, tps, bindwidth)
            return None
        self.count += 1
        action = SendRecvAction(job=self)
        msg = ''.join(('#', str(self.count), ' hello, world.', 'A' * self.pad_bytes))
        self.count_bytes += len(msg)
        action.data = msg
        action.remote_service = SERVICE
        action.remote_address = self.peer_address
        action.addCallBack( self.done )
        action.addErrorBack( self.fail )
        self.action = action
        if log.debugable :
            if len(self.action.data) < 256 :
                log.debug('  GO: (size=%d)%s [result:%s reason:%s]', len(self.action.data), `self.action.data`, self.action.result, self.action.reason)
            else :
                log.debug('  GO: (size=%d) [result:%s reason:%s]', len(self.action.data), self.action.result, self.action.reason)
        return action
        # nextAction()

    def done(self, data=None) :
        if data :
            self.count_bytes += len(data)
        if log.debugable :
            if len(data) < 256 :
                log.debug('done CALLBACK: (size=%d)%s', len(data), `data`)
            else :
                log.debug('done CALLBACK: (size=%d)', len(data))
        # done()

    def fail(self, reason=None) :
        log.debug('fail CALLBACK: %s', `reason`)
        # fail()

    # class ClientJob

#######################################################################

HOST = "127.0.0.1"
PORT = 54344

def main(options):
    if options.verbose :
        log.enableDebug()
    else :
        log.disableDebug()
    if options.times > 0 :
        times = options.times
    else :
        times = 10

    address = (HOST, PORT)
    c = Jujube()
    c.connectTCP(address)

    job = ClientJob(address, times=times, bytes=options.bytes)
    c.addJob(job)

    c.run()
    # main()

if __name__ == '__main__' :
    from optparse import OptionParser
    parser = OptionParser()
    parser.add_option("-v", "--verbose", dest="verbose", action="store_true", default=False,
                        help='show detail information')
    parser.add_option("", "--times", dest="times", type="int", default=10,
                        help='times of ping-pong between beater and echoer')
    parser.add_option("", "--bytes", dest="bytes", type="int", default=0,
                        help='bytes of message for ping-pong between beater and echoer')
    parser.add_option("", "--profile", dest="profile", action="store_true", default=False,
                        help='show profile information')
    (options, args) = parser.parse_args()
    if options.profile :
        prof_file = 'prof.beat.txt'
        import cProfile
        cProfile.run("main(options)", prof_file)
        import pstats
        p = pstats.Stats(prof_file)
        #p.sort_stats("time").print_stats()
        p.sort_stats("cumulative").print_stats()
    else :
        main(options)

    import sys
    sys.exit(0)
